package com.gitee.feizns.wx.service.impl;

import com.gitee.feizns.wx.service.ex.InvalidMarkerNameException;
import com.gitee.feizns.wx.service.wechat.impl.RemoteChatServiceImpl;
import com.gitee.feizns.wx.domain.ao.JsApiTicketAo;
import com.gitee.feizns.wx.domain.pojo.Wx;
import com.gitee.feizns.wx.domain.props.WeChatProperties;
import com.gitee.feizns.wx.domain.vo.JsApiTicketVo;
import com.gitee.feizns.wx.domain.vo.WxVo;
import com.gitee.feizns.wx.mapper.WxMapper;
import com.gitee.feizns.wx.service.WeChatService;
import com.gitee.feizns.wx.service.wechat.RemoteWeChatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @author feizns
 * @since 2019/7/15
 */
@Service
@EnableConfigurationProperties(WeChatProperties.class)
public class WeChatServiceImpl implements WeChatService {

    @Autowired
    private WxMapper wxMapper;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private WeChatProperties weChatProperties;

    /**
     * appId 对 remoteService
     */
    private ConcurrentHashMap<String, RemoteWeChatService> remoteWeChatServiceMap = new ConcurrentHashMap<>();

    @Override
    public JsApiTicketVo getJsApiTicket(String name, JsApiTicketAo ao) {
        Wx wx = checkByMarkName(name);
        RemoteWeChatService service = getService(wx);
        return service.getJsApiTicket(ao.getUrl());
    }

    @Override
    public WxVo getByName(String name) {
        return wxMapper.getWxVoByName(name);
    }

    private RemoteWeChatService getService(Wx wx) {
        RemoteWeChatService service = remoteWeChatServiceMap.get(wx.getAppId());
        if ( service == null ) {
            RemoteChatServiceImpl ret = new RemoteChatServiceImpl(wx.getAppId(), wx.getAppSecret(), weChatProperties, restTemplate);
            remoteWeChatServiceMap.put(wx.getAppId(), ret);
            return ret;
        }
        return service;
    }

    private Wx checkByMarkName(String name) {
        Wx wx = wxMapper.getByName(name);
        if ( wx == null )
            throw new InvalidMarkerNameException();
        return wx;
    }

}
